/*
 * Copyright (C) 2023 HiHope Open Source Organization
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

 #include <stdio.h>
 #include <unistd.h>
 #include "ohos_init.h"
 #include "cmsis_os2.h"
 #include "iot_gpio.h"
 #include "iot_pwm.h"
 #include "iot_errno.h"
 #include "hi_io.h"
 
 // 硬件引脚配置
 #define RGB_RED_PIN       2     // 红色LED控制引脚
 #define RGB_GREEN_PIN     8     // 绿色LED控制引脚
 #define RGB_BLUE_PIN      7     // 蓝色LED控制引脚
 #define USER_BUTTON_PIN   14    // 用户按键引脚
 
 // PWM参数配置
 #define MAX_DUTY_CYCLE    100   // PWM最大占空比
 #define PWM_FREQUENCY     64000 // PWM频率
 #define ANIMATION_DELAY   50000 // 动画延迟(微秒)
 #define TASK_STACK_SIZE   4096  // 任务栈大小
 
 // PWM通道定义
 #define PWM_CHANNEL_RED   2     // 红色PWM通道
 #define PWM_CHANNEL_GREEN 0     // 绿色PWM通道
 #define PWM_CHANNEL_BLUE  1     // 蓝色PWM通道
 
 // 亮度变化系数
 #define BRIGHTNESS_FACTOR 2     // 亮度变化倍数
 
 /**
  * @brief 初始化用户按键GPIO
  * 
  * 配置按键引脚为输入模式，并启用上拉电阻
  */
 static void InitializeUserButton(void)
 {
     // 初始化GPIO
     IoTGpioInit(USER_BUTTON_PIN);
     
     // 设置引脚功能为GPIO
     hi_io_set_func(USER_BUTTON_PIN, HI_IO_FUNC_GPIO_14_GPIO);
     
     // 配置为输入模式
     IoTGpioSetDir(USER_BUTTON_PIN, IOT_GPIO_DIR_IN);
     
     // 启用上拉电阻
     hi_io_set_pull(USER_BUTTON_PIN, HI_IO_PULL_UP);
 }
 
 /**
  * @brief 等待用户按键按下并释放
  * 
  * 检测按键按下和释放，包含消抖处理
  */
 static void WaitForButtonAction(void)
 {
     IotGpioValue buttonState;
     
     // 等待按键按下(低电平)
     while (1) {
         IoTGpioGetInputVal(USER_BUTTON_PIN, &buttonState);
         if (buttonState == IOT_GPIO_VALUE0) {
             break;
         }
         usleep(10000); // 10ms检测间隔
     }
     usleep(100000); // 100ms消抖延时
     
     // 等待按键释放(高电平)
     while (1) {
         IoTGpioGetInputVal(USER_BUTTON_PIN, &buttonState);
         if (buttonState == IOT_GPIO_VALUE1) {
             break;
         }
         usleep(10000); // 10ms检测间隔
     }
     usleep(100000); // 100ms消抖延时
 }
 
 /**
  * @brief 控制LED呼吸灯效果
  * 
  * @param pwmChannel PWM通道号
  * @param ledPin LED控制引脚
  * @param ledColor 颜色名称(用于打印)
  */
 static void ControlLedBreathingEffect(int pwmChannel, int ledPin, const char* ledColor)
 {
     printf("%s LED breathing effect started...\n", ledColor);
     
     // 配置引脚PWM功能
     hi_io_set_func(ledPin, 
                   (ledColor[0] == 'R') ? HI_IO_FUNC_GPIO_2_PWM2_OUT :
                   (ledColor[0] == 'G') ? HI_IO_FUNC_GPIO_9_PWM0_OUT :
                   HI_IO_FUNC_GPIO_8_PWM1_OUT);
     
     // 初始化PWM
     IoTPwmInit(pwmChannel);
     
     // 亮度渐增
     for (int brightness = 1; brightness < MAX_DUTY_CYCLE; brightness *= BRIGHTNESS_FACTOR) {
         IoTPwmStart(pwmChannel, brightness, PWM_FREQUENCY);
         usleep(ANIMATION_DELAY);
     }
     
     // 亮度渐减
     for (int brightness = MAX_DUTY_CYCLE; brightness > 1; brightness /= BRIGHTNESS_FACTOR) {
         IoTPwmStart(pwmChannel, brightness, PWM_FREQUENCY);
         usleep(ANIMATION_DELAY);
     }
     
     // 停止PWM输出
     IoTPwmStop(pwmChannel);
 }
 
 /**
  * @brief RGB LED控制任务
  * 
  * @param arg 任务参数(未使用)
  */
 static void RgbLedControlTask(void *arg)
 {
     (void)arg;
     
     // 初始化硬件
     InitializeUserButton();
     IoTGpioInit(RGB_RED_PIN);
     IoTGpioInit(RGB_GREEN_PIN);
     IoTGpioInit(RGB_BLUE_PIN);
 
     while (1) {
         printf("Press button to start RGB LED sequence...\n");
         WaitForButtonAction();
         
         // 红色LED呼吸效果
         ControlLedBreathingEffect(PWM_CHANNEL_RED, RGB_RED_PIN, "Red");
         
         WaitForButtonAction();
         
         // 绿色LED呼吸效果
         ControlLedBreathingEffect(PWM_CHANNEL_GREEN, RGB_GREEN_PIN, "Green");
         
         WaitForButtonAction();
         
         // 蓝色LED呼吸效果
         ControlLedBreathingEffect(PWM_CHANNEL_BLUE, RGB_BLUE_PIN, "Blue");
     }
 }
 
 /**
  * @brief 创建RGB LED控制任务
  */
 static void StartRgbLedDemo(void)
 {
     osThreadAttr_t taskAttributes = {
         .name = "RgbLedControlTask",
         .attr_bits = 0U,
         .cb_mem = NULL,
         .cb_size = 0U,
         .stack_mem = NULL,
         .stack_size = TASK_STACK_SIZE,
         .priority = osPriorityNormal
     };
 
     if (osThreadNew(RgbLedControlTask, NULL, &taskAttributes) == NULL) {
         printf("[Error] Failed to create RgbLedControlTask!\n");
     }
 }
 
 // 注册应用初始化函数
 APP_FEATURE_INIT(StartRgbLedDemo);
 